Requester = function() {}

Requester.prototype.onreadystatechange = function() {
  this.responder.onresponse(this.xmlHttpRequest);
}

Requester.prototype.request = function(method, url, body, responder,
                                       displayElementIdPrefix) {
  var headers = constructRequestHeaders(getTokenFromCookie());
  displayRequest(method, url, body, headers, displayElementIdPrefix);
  this.responder = responder;
  if (isXMLHttpRequestDefined()) {
    this.xmlHttpRequest = newXMLHttpRequest();
  } else if (isActiveXObjectDefined()) {
    this.xmlHttpRequest = newActiveXObject("Microsoft.XMLHTTP");
  }
  var self = this;
  this.xmlHttpRequest.onreadystatechange = function() {
    self.onreadystatechange();
  };
  this.xmlHttpRequest.open(method, url, /*async*/true);
  for (var headerName in headers) {
    this.xmlHttpRequest.setRequestHeader(headerName, headers[headerName]);
  }
  this.xmlHttpRequest.send(body);
}

function isActiveXObjectDefined() {
  return typeof ActiveXObject != "undefined";
}

function isXMLHttpRequestDefined() {
  return typeof XMLHttpRequest != "undefined";
}

function newActiveXObject(progId) {
  return new ActiveXObject(progId);
}

function newXMLHttpRequest() {
  return new XMLHttpRequest();
}

function constructRequestHeaders(token) {
  var headers = new Array();
  headers["Content-Type"] = "application/atom+xml";
  headers["Authorization"] = 'AuthSub token="' + token + '"';
  headers["X-Google-Key"] = 'key=ABQIAAAA7VerLsOcLuBYXR7vZI2NjhTRERdeAiwZ9EeJWta3L_JZVS0bOBRIFbhTrQjhHE52fqjZvfabYYyn6A';
  return headers;
}

function displayRequest(method, url, body, headers, displayElementIdPrefix) {
  var requestDiv = document.getElementById(displayElementIdPrefix + "request");
  requestDiv.innerHTML =
  "<pre>" +
  method + " " + url + "\n" +
  headerStringsFromHeaders(headers).join("\n") + "\n" +
  "\n" +
  (body == null ? "" : htmlEscape(body)) +
  "</pre>";
}

function headerStringsFromHeaders(headers) {
  var headerStrings = new Array();
  for (var headerName in headers) {
    headerStrings.push(headerName + ": " + headers[headerName]);
  }
  return headerStrings;
}
